package com.tao.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tao.clients.*;
import com.tao.param.ProductHotParam;
import com.tao.param.ProductIdsParam;
import com.tao.param.ProductSaveParam;
import com.tao.param.ProductSearchParam;
import com.tao.pojo.Picture;
import com.tao.pojo.Product;
import com.tao.product.mapper.PictureMapper;
import com.tao.product.mapper.ProductMapper;
import com.tao.product.service.ProductService;
import com.tao.to.OrderToProduct;
import com.tao.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 86130
 */
@Slf4j
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {

    @Resource
    private OrderClient orderClient;

    @Resource
    private CartClient cartClient;

    @Resource
    private CollectClient collectClient;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    /**
     * 引用feign客户端需要再启动类添加配置注解
     */
    private CategoryClient categoryClient;

    @Autowired
    private PictureMapper pictureMapper;

    @Autowired
    private SearchClient searchClient;


    /**
     * 根据单类别名称查询热门商品，最多7条数据
     * 1. 根据类别名称 调用 feign客户端访问类别服务获取类别的数据
     * 2. 成功 继续根据类别id查询商品数据  [热门 销售量倒序 查询7]
     * 3. 结果封装即可
     * @param categoryName 类别名称
     * @return r
     */
    @Cacheable(value ="list.product" ,key ="#categoryName" ,cacheManager = "cacheManagerHour")
    @Override
    public R promo(String categoryName) {

        R r = categoryClient.byName(categoryName);
        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.promo业务结束，结果：{}", "类别查询失败！");
            return r;
        }

        // 类别服务中 data = category --- feign {json}  ----- product服务 LinkedHashMap jackson

        LinkedHashMap<String,Object>  map = (LinkedHashMap<String, Object>) r.getData();
        Integer categoryId = (Integer) map.get("category_id");

        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("category_id", categoryId);
        productQueryWrapper.orderByDesc("product_sales");

        //分页
        IPage<Product> page = new Page<>(1, 7);

        //返回的是包装数据，内部有对应的商品集合，也有分页的参数
        page = productMapper.selectPage(page, productQueryWrapper);

        //指定页的数据
        List<Product> productList = page.getRecords();

        //获取总条数
        long total = page.getTotal();

        log.info("ProductServiceImpl.promo业务结束，结果：{}", productList);
        return R.ok("数据查询成功", productList);
    }

    /**
     * 查询类别商品集合
     *
     * @return
     */
    @Override
    public R cList() {

        R r = categoryClient.list();
        log.info("ProductServiceImpl.cList业务结束，结果：{}", r);

        return r;
    }

    /**
     * 多类别人额商品查询，根据类别名称集合至多查询7条
     *  1. 调用类别服务
     *  2. 类别集合id查询商品
     *  3. 结果集封装即可
     * @param productHotParam 类别名称集合
     * @return r
     */
    @Cacheable(value = "list.product",key = "#productHotParam.categoryName")
    @Override
    public R hots(ProductHotParam productHotParam) {

        R r = categoryClient.hots(productHotParam);
        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.hots业务结束，结果：{}", r.getMsg());
            return r;
        }

        List<Object> ids = (List<Object>) r.getData();

        //进行商品数据查询
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.in("category_id", ids);
        productQueryWrapper.orderByDesc("product_sales");

        IPage<Product> page = new Page<>(1, 7);
        page = productMapper.selectPage(page, productQueryWrapper);
        List<Product> records = page.getRecords();
        R ok = R.ok("多类别热门商品查询成功", records);
        log.info("ProductServiceImpl.hots业务结束，结果：{}", ok);
        return ok;
    }


    /**
     * 通用型的业务
     * 传入了类别id，根据id查询并分页
     * 没有传入类别id，查询全部
     *
     * @param productIdsParam
     * @return
     */
    @Cacheable(value = "list.product",key = "#productIdsParam.categoryID+'-'+#productIdsParam.currentPage+'-'+#productIdsParam.pageSize")
    @Override
    public R byCategory(ProductIdsParam productIdsParam) {

        List<Integer> categoryID = productIdsParam.getCategoryID();
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        if (!categoryID.isEmpty()) {
            queryWrapper.in("category_id", categoryID);
        }

        IPage<Product> page = new Page<>(productIdsParam.getCurrentPage(), productIdsParam.getPageSize());

        page = productMapper.selectPage(page, queryWrapper);

        //结果集封装
        R ok = R.ok("查询成功！", page.getRecords(), page.getTotal());
        log.info("ProductServiceImpl.byCategory业务结束，结果：{}", ok);

        return ok;
    }

    /**
     * 根据商品id查询商品详情信息
     *
     * @param productID
     * @return
     */
    @Cacheable(value = "product",key = "#productID")
    @Override
    public R detail(Integer productID) {

        Product product = productMapper.selectById(productID);
        R ok = R.ok(product);
        log.info("ProductServiceImpl.detail业务结束，结果：{}", ok);

        return ok;
    }

    /**
     * 查询商品对应的图片详情集合
     *
     * @param productID
     * @return
     */
    @Cacheable(value = "picture",key = "#productID")
    @Override
    public R pictures(Integer productID) {

        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", productID);
        List<Picture> pictures = pictureMapper.selectList(queryWrapper);
        R ok = R.ok(pictures);
        log.info("ProductServiceImpl.pictures业务结束，结果：{}", ok);

        return ok;
    }

    /**
     * 搜索服务调用获取全部商品数据
     * 进行同步
     *
     * @return 商品数据集合
     */
    @Cacheable(value = "list.category",key = "#root.methodName",cacheManager = "cacheManagerDay")
    @Override
    public List<Product> allList() {
        List<Product> productList = productMapper.selectList(null);
        log.info("ProductServiceImpl.allList业务结束，结果：{}", productList.size());
        return productList;
    }

    /**
     * 搜索业务，需要调用搜素服务
     *
     * @param productSearchParam
     * @return
     */
    @Override
    public R search(ProductSearchParam productSearchParam) {

        R r = searchClient.search(productSearchParam);
        log.info("ProductServiceImpl.search业务结束，结果：{}",r);
        return r;
    }

    /**
     * 根据商品id集合查询商品信息
     *
     * @param productIds
     * @return
     */
    @Cacheable(value = "list.product",key = "#productIds")
    @Override
    public R ids(List<Integer> productIds) {

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("product_id", productIds);
        List<Product> productList = productMapper.selectList(queryWrapper);

        R r = R.ok("类别信息查询成功!", productList);
        log.info("ProductServiceImpl.ids业务结束，结果：{}",r);

        return r;
    }

    /**
     * 根据商品id查询商品id集合
     *
     * @param productIds
     * @return
     */
    @Override
    public List<Product> cartList(List<Integer> productIds) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("product_id", productIds);

        List<Product> productList = productMapper.selectList(queryWrapper);
        log.info("ProductServiceImpl.cartList业务结束，结果：{}",productList);

        return productList;
    }

    /**
     * 修改库存和增加销售量
     *
     * @param orderToProducts
     */
    @Override
    public void subNumber(List<OrderToProduct> orderToProducts) {

        //将集合转成map
        Map<Integer, OrderToProduct> map = orderToProducts.stream().collect(Collectors.toMap(OrderToProduct::getProductId, v -> v));
        //获取商品的id集合
        Set<Integer> productIds = map.keySet();
        //查询集合对应的商品信息
        List<Product> productList = productMapper.selectBatchIds(productIds);
        //修改商品信息
        for (Product product : productList) {
            Integer num = map.get(product.getProductId()).getNum();
            //减库存
            product.setProductNum(product.getProductNum() - num);
            //加销售量
            product.setProductSales(product.getProductSales() + num);
        }
        //批量更新
        this.updateBatchById(productList);
        log.info("ProductServiceImpl.subNumber业务结束，结果：库存和销售量的修改完毕");
    }

    /**
     * 类别对应的商品数量查询
     *
     * @param categoryId
     * @return
     */
    @Override
    public Long adminCount(Integer categoryId) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id", categoryId);
        Long count = baseMapper.selectCount(queryWrapper);
        log.info("ProductServiceImpl.adminCount业务结束，结果：{}",count);
        return count;
    }

    /**
     * 商品保存
     *
     * @param productSaveParam
     * @return
     */
    @CacheEvict(value = "list.product", allEntries = true)
    @Override
    public R adminSave(ProductSaveParam productSaveParam) {
        Product product = new Product();
        BeanUtils.copyProperties(productSaveParam, product);

        //商品数据插入
        int rows = productMapper.insert(product);
        log.info("ProductServiceImpl.adminSave业务结束，结果：{}", rows);

        String productPicture = product.getProductPicture();
        if (!StringUtils.isEmpty(productPicture)) {
            //截取特殊字符串的时候 用  \\ 或 [] 包含
            String[] urls = productPicture.split("\\+");
            for (String url : urls) {
                Picture picture = new Picture();
                picture.setProductId(product.getProductId());
                picture.setProductPicture(url);
                //插入商品图片
                pictureMapper.insert(picture);
            }
        }
        //同步搜索服务的数据
        searchClient.saveOrUpdate(product);
        return R.ok("商品数据添加成功");
    }

    /**
     * 商品更新
     *
     * @param product
     * @return
     */
    @Override
    public R adminUpdate(Product product) {
        productMapper.updateById(product);
        //同步搜索服务的数据
        searchClient.saveOrUpdate(product);
        return R.ok("商品数据更新成功");
    }

    /**
     * 删除商品
     *
     * @param productId
     * @return
     */
    @Caching(
            evict = {
                    @CacheEvict(value = "list.product",allEntries = true),
                    @CacheEvict(value = "product",key = "#productId")
            }
    )
    @Override
    public R adminRemove(Integer productId) {
        R check = cartClient.check(productId);
        if ("004".equals(check.getCode())) {
            log.info("ProductServiceImpl.adminRemove业务结束，结果：{}",check.getMsg());
            return check;
        }

        check = orderClient.check(productId);
        if ("004".equals(check.getCode())) {
            log.info("ProductServiceImpl.adminRemove业务结束，结果：{}",check.getMsg());
            return check;
        }

        //删除商品
        productMapper.deleteById(productId);
        //删除商品图片
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", productId);
        pictureMapper.delete(queryWrapper);
        //删除收藏中的商品
        collectClient.remove(productId);
        //同步数据
        searchClient.remove(productId);
        return R.ok("商品删除成功");
    }
}
